﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TicTacToe
{
    public class Maximizer : IMinMax
    {
        private int _currentSearchLevel;
        private List<Minimizer> _childNodes;
        public GameBoard.SquareStatus[,] _currentState { get; set;}
        public double _heuristic { get; private set; }

        public Maximizer(GameBoard.SquareStatus[,] currentState, int currentSearchLevel)
        {
            _currentState = currentState;
            _currentSearchLevel = currentSearchLevel;
            _heuristic = Double.NegativeInfinity;
            _childNodes = new List<Minimizer>();
            if (currentSearchLevel > 0)
                PopulateChildNodes();
        }

        public double Search(double alpha, double beta)
        {
            if (GameBoard.CheckIfCrossWon(_currentState))
            {
                _heuristic = double.PositiveInfinity;
                return _heuristic;
            }
            else if (GameBoard.CheckIfCircleWon(_currentState))
            {
                _heuristic = double.NegativeInfinity;
                return _heuristic;
            }

            else if (GameBoard.CheckForDraw(_currentState))
            {
                _heuristic = 0.0;
                return _heuristic;
            }

            else if (_currentSearchLevel == 0)
            {
                _heuristic = CalculateStaticEvaluation();
                return _heuristic;
            }
            foreach(var child in _childNodes)
            {
                double V;

                if (alpha < beta)
                {
                    V = child.Search(alpha, beta);
                    
                    alpha = _heuristic = (V > alpha ? V : alpha);
                }
                else
                    break;

                //_heuristic = (nodeHeuristic > _heuristic ? nodeHeuristic : _heuristic);
            }

            return _heuristic;
        }

        private double CalculateStaticEvaluation()
        {
            double h = 0;
            for(int i = 0; i < _currentState.GetLength(0); i++)
                for (int j = 0; j < _currentState.GetLength(1); j++)
                {
                    if (_currentState[i, j] == GameBoard.SquareStatus.Cross || _currentState[i, j] == GameBoard.SquareStatus.CrossSelected)
                        h += GameBoard.StaticEvaluation[i][j];
                }

            return h;
        }

        public void PopulateChildNodes()
        {
            for(int i = 0; i < _currentState.GetLength(0); i++)
                for (int j = 0; j < _currentState.GetLength(1); j++) {
                    if (_currentState[i, j] == GameBoard.SquareStatus.Empty || _currentState[i, j] == GameBoard.SquareStatus.EmptySelected)
                    {
                        var newState = _currentState.Clone() as GameBoard.SquareStatus[,];
                        newState[i, j] = GameBoard.SquareStatus.Cross;
                        _childNodes.Add(new Minimizer(newState, _currentSearchLevel-1));
                    }
                }
        }

        public GameBoard.SquareStatus[,] NextMove()
        {
            _heuristic = Search(double.NegativeInfinity, double.PositiveInfinity);

            return _childNodes.Find(e => e._heuristic == _heuristic)._currentState;
        }
    }
}